import logger from '../core/logger';
import apiInfo from './core/apiInfo';
import dataInfo from './core/dataInfo';
import apiProvider from './core/apiProvider';
import { clientBase } from './core/clientBase';
import timeLine from '../model/bangumi/timeLine';
import seasonTag from '../model/bangumi/seasonTag';
import allBangumi from '../model/bangumi/allBangumi';
import { emptyData } from '../model/common/emptyData';
import returnModel from '../model/common/returnModel';
import bangumiData from '../model/bangumi/bangumiData';
import bangumiHome from '../model/bangumi/bangumiHome';
import bangumiDetail from '../model/bangumi/bangumiDetail';
import followResult from '../../common/model/bangumi/followResult';

class bangumiClient extends clientBase {
  constructor() {
    super();
  }

  condition(typeId: number): Promise<returnModel<Array<seasonTag>>> {
    return new Promise((resolve) => {
      try {
        let info = new apiInfo("https://api.bilibili.com/pgc/season/index/condition", `&season_type=${typeId}&type=0`, true);
        this.client.getResult(info).then((res) => {
          if (res.code == '0') {
            let output: Array<seasonTag> = [];
            let arr: Array<seasonTag> = res.data.filter;
            arr.forEach((i) => {
              let o = new seasonTag(i.id, i.name, i.values);
              o.toSelected();
              output.push(o);
            });
            resolve(this.buildSuccessResult<Array<seasonTag>>(output));
          } else
            resolve(this.buildFailedResult<Array<seasonTag>>(res.message));
        });
      } catch (e) {
        logger.error(e);
        resolve(this.buildExceptionResult<Array<seasonTag>>(e));
      }
    });
  }

  getTimeline(type: number): Promise<returnModel<Array<timeLine>>> {
    return new Promise((resolve) => {
      try {
        let url = `https://bangumi.bilibili.com/web_api/${(type == 1 ? 'timeline_global' : 'timeline_cn')}`;
        this.client.getResult(url).then((res) => {
          if (res.code == '0') {
            let data: Array<timeLine> = res.result;
            resolve(this.buildSuccessResult<Array<timeLine>>(data));
          } else {
            resolve(this.buildFailedResult<Array<timeLine>>(res.message));
          }
        });
      } catch (e) {
        logger.error(e);
        resolve(this.buildExceptionResult<Array<timeLine>>(e));
      }
    });
  }

  moveStatus(seasonId: number, status: number): Promise<returnModel<emptyData>> {
    return new Promise((resolve) => {
      try {
        let info = new dataInfo(`season_id=${seasonId}&status=${status}`, apiProvider.Build5);
        this.client.postResult('https://api.bilibili.com/pgc/app/follow/status/update', info).then((res) => {
          if (res.code == '0')
            resolve(this.buildSuccessResult<emptyData>());
          else
            resolve(this.buildFailedResult<emptyData>(res.message));
        });
      } catch (e) {
        logger.error(e);
        resolve(this.buildExceptionResult<emptyData>(e));
      }
    });
  }

  getRecommend(): Promise<returnModel<bangumiHome>> {
    return new Promise((resolve) => {
      try {
        let info = new apiInfo("https://bangumi.bilibili.com/appindex/follow_index_page");
        this.client.getResult(info).then((res) => {
          if (res.code == '0') {
            let data: bangumiHome = res.result;
            resolve(this.buildSuccessResult<bangumiHome>(data));
          } else
            resolve(this.buildFailedResult<bangumiHome>(res.message));
        });
      } catch (e) {
        logger.error(e);
        resolve(this.buildExceptionResult<bangumiHome>(e));
      }
    });
  }

  getDetail(mediaId: number): Promise<returnModel<bangumiDetail>> {
    return new Promise((resolve) => {
      try {
        let info = new apiInfo('https://api.bilibili.com/pgc/view/app/season', `season_id=${mediaId}`, true);
        this.client.getResult(info).then((res) => {
          if (res.code == '0') {
            let data: bangumiDetail = res.result;
            resolve(this.buildSuccessResult<bangumiDetail>(data));
          } else
            resolve(this.buildFailedResult<bangumiDetail>(res.message));
        });
      } catch (e) {
        logger.error(e);
        resolve(this.buildExceptionResult<bangumiDetail>(e));
      }
    });
  }

  getInfo(bangumiId: string): Promise<returnModel<bangumiData>> {
    return new Promise((resolve) => {
      try {
        let info = new apiInfo("https://api.bilibili.com/pgc/view/app/season", `&season_id=${bangumiId}`, true);
        this.client.getResult(info).then((res) => {
          if (res.code == '0') {
            let data: bangumiData = res.result;
            resolve(this.buildSuccessResult<bangumiData>(data));
          } else
            resolve(this.buildFailedResult<bangumiData>(res.message));
        });
      } catch (e) {
        logger.error(e);
        resolve(this.buildExceptionResult<bangumiData>(e));
      }
    });
  }

  cancelFollow(seasonId: number, seasonType: number): Promise<returnModel<emptyData>> {
    return new Promise((resolve) => {
      try {
        let info = new apiInfo("https://bangumi.bilibili.com/follow/api/season/unfollow", `&season_id=${seasonId}&season_type=${seasonType}`, true);
        this.client.getResult(info).then((res) => {
          if (res.code == '0')
            resolve(this.buildSuccessResult<emptyData>());
          else
            resolve(this.buildFailedResult<emptyData>(res.message));
        });
      } catch (e) {
        logger.error(e);
        resolve(this.buildExceptionResult<emptyData>(e));
      }
    });
  }

  getFollow(type: string, pn: number, status: number): Promise<returnModel<followResult>> {
    return new Promise((resolve) => {
      try {
        let info = new apiInfo(`https://api.bilibili.com/pgc/app/follow/v2/${type}`, `&pn=${pn}&ps=20&status=${status}`, true);
        this.client.getResult(info).then((res) => {
          if (res.code == '0') {
            let m: followResult = res.data.result;
            resolve(this.buildSuccessResult<followResult>(m));
          } else
            resolve(this.buildFailedResult<followResult>(res.message));
        });
      } catch (e) {
        logger.error(e);
        resolve(this.buildExceptionResult<followResult>(e));
      }
    });
  }

  getBangumiTag(conditions: string, typeId: number, pageNum: number): Promise<returnModel<Array<allBangumi>>> {
    return new Promise((resolve) => {
      try {
        let info = new apiInfo("https://api.bilibili.com/pgc/season/index/result", `&type=0&page=${pageNum}&pagesize=24&season_type=${typeId}${conditions}`);
        this.client.getResult(info).then((res) => {
          if (res.code == '0') {
            let data: Array<allBangumi> = res.data?.list;
            resolve(this.buildSuccessResult<Array<allBangumi>>(data));
          } else
            resolve(this.buildFailedResult<Array<allBangumi>>(res.message));
        });
      } catch (e) {
        logger.error(e);
        resolve(this.buildExceptionResult<Array<allBangumi>>(e));
      }
    });
  }

  getInfFromPlus(sid: string, type: number): Promise<returnModel<allBangumi>> {
    return new Promise((resolve) => {
      try {
        let url = `https://bangumi.bilibili.com/view/web_api/season?season_id=${sid}`;
        this.client.getResult(url).then((res) => {
          let data;
          let r: string = res.toString();
          if (type == 0) {
            r = r.replace("ep_id", "episode_id").replace("cid", "danmaku").replace("aid", "av_id");
            data = JSON.parse(r);
          } else {
            r = r.replace("ep_id", "episode_id").replace("cid", "danmaku").replace("aid", "av_id").replace("index_title", "long_title").replace("index", "title");
            data = JSON.parse(r).result.episodes;
          }
          resolve(this.buildSuccessResult<allBangumi>(data));
        });
      } catch (e) {
        logger.error(e);
        resolve(this.buildExceptionResult<allBangumi>(e));
      }
    });
  }
}
export default new bangumiClient();